home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
general
/
viewers
/
polyview
/
polyvw31.lha
/
Polyview3.1
/
new
/
pvrender.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-13
|
36KB
|
1,218 lines
/*****************************************************************************
* NCSA Polyview 3.1 *
* *
* Version 3.1 changes and additions by Gilles Bourhis. *
* Version 3 changes and additions by Marc Andreessen. *
* Version 2 by Brian Calvert. *
* *
* Software Development Group *
* National Center for Supercomputing Applications *
* University of Illinois at Urbana-Champaign *
* *
* This is BETA release software. As such it may contain software bugs and *
* exhibit inconsistencies. *
* *
* Please send bug reports to polyview@ncsa.uiuc.edu. *
* *
* Copyright (c) 1992 The Board of Trustees of the University of Illinois. *
* *
* Permission to use, copy, and modify this software and its *
* documentation for educational, research, and non-profit purposes is *
* hereby granted, provided that the above copyright notice, the original *
* authors names, and this permission notice appear in all such copies. *
* Any distribution of this software requires the explicit and written *
* authorization of the authors. *
* *
* The University of Illinois makes no representations about the *
* suitability of this software for any purpose. It is provided "as is" *
* without warranty of any kind. *
*****************************************************************************/
/* $Id: pvrender.c,v 1.2 93/08/13 13:18:23 gbourhis Exp $ */
#ifdef RCSLOG
$Log: pvrender.c,v $
* Revision 1.2 93/08/13 13:18:23 gbourhis
* correct viewpoint.
*
* Revision 1.1 92/09/18 10:55:26 marca
* Initial revision
*
#endif
#include "pv.h"
#define PI 3.14159265
/* Start of RenderMan-specific code. */
#ifdef RENDERMAN
/* Choose method for RenderMan interface. */
/* #define DUMP_CFILE */
#define DIRECT_RENDERMAN
#ifdef DIRECT_RENDERMAN
/* ------------------------------------------------------------------------ */
/* ------------------------ DIRECT RENDERMAN CODE ------------------------- */
/* ------------------------------------------------------------------------ */
#include <ri.h>
static RtColor rc[256];
static RtColor rc_default = {0.8, 0.8, 0.8};
static RtPoint rp[8];
static int num_vertices = 0;
static void rm_bgnpolygon (void)
{
num_vertices = 0;
return;
}
static void rm_v3f (float *vv)
{
/* Copy the vertex. */
rp[num_vertices][0] = vv[0];
rp[num_vertices][1] = vv[1];
rp[num_vertices][2] = vv[2];
/* Increment the count. */
num_vertices++;
return;
}
static void rm_endpolygon (void)
{
RiPolygon( (RtInt)num_vertices, RI_P, (RtPointer)rp, RI_NULL );
return;
}
static void rm_palettecpack (int c)
{
/* Suck the color out of preloaded array of RtColor's. */
RiColor(rc[c]);
}
/* ------------------------------------------------------------------------ */
/* ----------------------------- SPHERE SHIT ------------------------------ */
/* ------------------------------------------------------------------------ */
static float sphere_size;
/* 1 if vertices should be drawn as cubes. */
static int sphere_cubes;
#define L -.5 /* For x: left side */
#define RIGHT .5 /* For x: right side */
#define D -.5 /* For y: down side */
#define U .5 /* For y: upper side */
#define F .5 /* For z: far side */
#define N -.5 /* For z: near side */
/* UnitCube(): define a cube in the graphics environment */
static void UnitCube (void)
{
static RtPoint Cube[6][4] = {
{ {L,D,F}, {L,D,N}, {RIGHT,D,N}, {RIGHT,D,F} }, /* Bottom face */
{ {L,D,F}, {L,U,F}, {L,U,N}, {L,D,N} }, /* Left face */
{ {RIGHT,U,N}, {L,U,N}, {L,U,F}, {RIGHT,U,F} }, /* Top face */
{ {RIGHT,U,N}, {RIGHT,U,F}, {RIGHT,D,F}, {RIGHT,D,N} },
/* Right face */
{ {RIGHT,D,F}, {RIGHT,U,F}, {L,U,F}, {L,D,F} }, /* Far face */
{ {L,U,N}, {RIGHT,U,N}, {RIGHT,D,N}, {L,D,N} } /* Near face */
};
int i;
for( i = 0; i < 6; i++) /* Declare the cube */
RiPolygon( (RtInt) 4, RI_P, (RtPointer) Cube[i], RI_NULL);
}
static void rm_sphdraw (float *vv)
{
if (sphere_cubes)
{
RiTransformBegin ();
{
RiTranslate (vv[0], vv[1], vv[2]);
RiScale (sphere_size*2.0, sphere_size*2.0, sphere_size*2.0);
UnitCube ();
}
RiTransformEnd ();
}
else
{
RiTransformBegin();
{
RiTranslate ((RtFloat)vv[0], (RtFloat)vv[1], (RtFloat)vv[2]);
RiSphere (sphere_size, -sphere_size, sphere_size, 360.0, RI_NULL);
}
RiTransformEnd();
}
return;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------ LINE SHIT ------------------------------- */
/* ------------------------------------------------------------------------ */
/* Keep a static array of vertices and a count of the number
of vertices in the array. */
static float line_vv[20][3];
static int line_vv_count = 0;
static int line_cc[20];
static int line_cc_used = 0;
/* Static width of lines drawn as cylinders. */
static float line_width = 0.1;
/* This should be a window-local variable or something. */
static int cap_cylinders = 0;
static void DoCylinder (float line_width,
float x1, float y1, float z1,
float x2, float y2, float z2)
{
float offset[3], len, xang, yang;
if (FEQ(y1, y2))
xang = 3.14159265 * 0.5;
else
xang = atanf (sqrtf ((x2-x1)*(x2-x1)+(z2-z1)*(z2-z1))/(y2-y1));
yang = atan2f ((x2-x1),(z2-z1));
#if 0
if (yang != yang)
return;
#endif
xang *= 180.0 / 3.14159265;
yang *= 180.0 / 3.14159265;
offset[0] = (x1+x2)*0.5;
offset[1] = (y1+y2)*0.5;
offset[2] = (z1+z2)*0.5;
len = sqrtf( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) + (z2-z1)*(z2-z1) );
RiTransformBegin ();
{
RiTranslate( offset[0], offset[1], offset[2] );
RiRotate ( yang, 0.0, 1.0, 0.0 );
RiRotate ( xang, 1.0, 0.0, 0.0 );
RiScale ( 1.0, len, 1.0 );
RiRotate ( 90.0, 1.0, 0.0, 0.0 );
RiCylinder (line_width, -0.5, 0.5, 360.0, RI_NULL);
}
RiTransformEnd ();
return;
}
static void rm_linepalettecpack (int c)
{
/* Save this color index with the current vertex. */
line_cc[line_vv_count] = c;
/* Note that we are using colors for this line. */
line_cc_used = 1;
}
static void rm_bgnclosedline (void)
{
/* Starting a new line. */
line_vv_count = 0;
/* Haven't used any colors yet. */
line_cc_used = 0;
}
static void rm_endclosedline (void)
{
int i;
/* If we have one or fewer vertices, punt. */
if (line_vv_count < 2)
goto done;
/* For each vertex up to the second-to-last, make
a cylinder with the vertex and its successor. */
for (i = 0; i < line_vv_count - 1; i++)
{
if (line_cc_used)
RiColor (rc[line_cc[i]]);
else
RiColor (rc_default);
DoCylinder
(/* radius */ line_width,
/* end 1 */ line_vv[i][0], line_vv[i][1], line_vv[i][2],
/* end 2 */ line_vv[i+1][0], line_vv[i+1][1], line_vv[i+1][2]);
#if 0
if (cap_cylinders)
{
fprintf (rayfp, " disc\n");
if (line_cc_used)
fprintf (rayfp, " pal%1d\n", line_cc[i]);
fprintf (rayfp, " %s\n %f %f %f\n %f %f %f\n",
"line_width",
line_vv[i][0], line_vv[i][1], line_vv[i][2],
line_vv[i][0] - line_vv[i+1][0],
line_vv[i][1] - line_vv[i+1][1],
line_vv[i][2] - line_vv[i+1][2]);
fprintf (rayfp, " disc\n");
if (line_cc_used)
fprintf (rayfp, " pal%1d\n", line_cc[i]);
fprintf (rayfp, " %s\n %f %f %f\n %f %f %f\n",
"line_width",
line_vv[i+1][0], line_vv[i+1][1], line_vv[i+1][2],
line_vv[i+1][0] - line_vv[i][0],
line_vv[i+1][1] - line_vv[i][1],
line_vv[i+1][2] - line_vv[i][2]);
}
#endif
}
/* If there's more than 2 vertices, close the line. */
if (line_vv_count > 2)
{
i = line_vv_count - 1;
if (line_cc_used)
RiColor (rc[line_cc[i]]);
else
RiColor (rc_default);
DoCylinder
(/* radius */ line_width,
/* end 1 */ line_vv[i][0], line_vv[i][1], line_vv[i][2],
/* end 2 */ line_vv[0][0], line_vv[0][1], line_vv[0][2]);
#if 0
if (cap_cylinders)
{
fprintf (rayfp, " disc\n");
if (line_cc_used)
fprintf (rayfp, " pal%1d\n", line_cc[i]);
fprintf (rayfp, " %s\n %f %f %f\n %f %f %f\n",
"line_width",
line_vv[i][0], line_vv[i][1], line_vv[i][2],
line_vv[i][0] - line_vv[0][0],
line_vv[i][1] - line_vv[0][1],
line_vv[i][2] - line_vv[0][2]);
fprintf (rayfp, " disc\n");
if (line_cc_used)
fprintf (rayfp, " pal%1d\n", line_cc[i]);
fprintf (rayfp, " %s\n %f %f %f\n %f %f %f\n",
"line_width",
line_vv[0][0], line_vv[0][1], line_vv[0][2],
line_vv[0][0] - line_vv[i][0],
line_vv[0][1] - line_vv[i][1],
line_vv[0][2] - line_vv[i][2]);
}
#endif
}
done:
line_vv_count = 0;
return;
}
static void rm_linev3f (float *vv)
{
/* Store this vertex. */
line_vv[line_vv_count][0] = vv[0];
line_vv[line_vv_count][1] = vv[1];
line_vv[line_vv_count][2] = vv[2];
/* Increment the count. */
line_vv_count++;
return;
}
/* ------------------------------------------------------------------------ */
/* --------------------------- rm_draw_vertices --------------------------- */
/* ------------------------------------------------------------------------ */
static int rm_draw_vertices (state_t *state, window_t *win, object_t *obj,
objinfo_t *info)
{
long count;
Vdata_t **vdata;
Vdata_t *vcolor_v;
Vdata_t *pcoord_v;
float (*pcoord)[DIMS];
int *vcolor;
char *picked;
int single_color;
/* Get pointers to the pertinent data sets */
vdata = obj->u.obj.vdata;
vcolor_v = get_vdata(state, vdata[VCOLOR]);
if ((pcoord_v = get_vdata(state, vdata[PCOORD])) == NULL)
return ST_OKAY;
/* Set up the consolidated coordinate array pointer. */
pcoord = (float (*)[DIMS]) pcoord_v->data;
count = pcoord_v->stats[0].rec_count;
assert (pcoord_v->stats[0].type == PVFLOAT);
if (FEQ(win->sphere_size, 0.0))
sphere_size = win->max_width * 0.01;
else
sphere_size = win->sphere_size;
sphere_cubes = (win->sphere_depth == 1);
if (vcolor_v == NULL || vcolor_v->data == NULL)
{
/* No color information. Use foreground and draw the */
/* appropriate shapes. */
while (count > 0)
{
{ /* not selected */
float params[4];
params[0] = (*pcoord)[0];
params[1] = (*pcoord)[1];
params[2] = (*pcoord)[2];
params[3] = win->sphere_size;
rm_sphdraw (params);
}
/* Move to the next x, y, z set and decrement the */
/* count. */
pcoord++;
count--;
}
}
else
{
/* Set pointers to the actual data and the size of the data */
/* sets. */
assert (vcolor_v->stats[0].type == PVINTEGER);
/* There is color information. Get it and use it to draw the */
/* appropriate shapes. */
vcolor = (int *) vcolor_v->data;
while (count > 0)
{
{ /* not selected */
float params[4];
rm_palettecpack(*vcolor);
params[0] = (*pcoord)[0];
params[1] = (*pcoord)[1];
params[2] = (*pcoord)[2];
params[3] = win->sphere_size;
rm_sphdraw (params);
}
/* Move to the next x, y, z set, color entry, and */
/* decrement the count. */
pcoord++;
vcolor++;
count--;
}
}
return ST_OKAY;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
static int rm_draw_edges (state_t *state, window_t *win, object_t *obj,
objinfo_t *info)
{
long count;
Vdata_t **vdata, *vcolor_v, *pcoord_v, *connect_v;
float (*pcoord)[DIMS];
int *vcolor, *connect;
char *picked;
int i, nvert, vertex;
/* Set the width of the cylinders. */
line_width = WIN_MAXWIDTH(win) * 0.0005 * (float)(win->line_width);
/* Get pointers to the pertinent data sets. */
vdata = obj->u.obj.vdata;
vcolor_v = get_vdata(state, vdata[VCOLOR]);
if ((connect_v = get_vdata(state, vdata[CONNECT])) == NULL)
if ((connect_v = get_vdata(state, vdata[MCONNECT])) == NULL)
{
rm_draw_vertices(state, win, obj, info);
return ST_OKAY;
}
if ((pcoord_v = get_vdata(state, vdata[PCOORD])) == NULL)
return ST_OKAY;
/* Collect connectivity information for drawing. */
connect = (int *) connect_v->data;
count = connect_v->stats[0].rec_count;
nvert = connect_v->stats[0].rec_size;
/* Set up the consolidated coordinate array pointer. */
pcoord = (float (*)[DIMS]) pcoord_v->data;
assert (pcoord_v->stats[0].type == PVFLOAT);
/* If there is no vertex color information, draw without it */
/* (use the FOREGROUND color). Otherwise, grab the color array. */
if (vcolor_v == NULL || vcolor_v->data == NULL)
{
/* No color information. Use foreground and draw the */
/* appropriate shapes. */
while (count > 0)
{
rm_bgnclosedline();
for (i = nvert; i > 0; i--)
{
if ( (vertex = *(connect++)-1) == -1)
{
connect += i-1;
break;
}
rm_linev3f(pcoord[vertex]);
}
rm_endclosedline();
count--;
}
}
else
{
/* Set pointers to the actual data and the size of the data */
/* sets. */
assert (vcolor_v->stats[0].type == PVINTEGER);
/* There is color information. Get it and use it to draw the */
/* appropriate shapes. */
vcolor = (int *) vcolor_v->data;
while (count > 0)
{
rm_bgnclosedline();
for (i = nvert; i > 0; i--)
{
if ( (vertex = *(connect++)-1) == -1)
{
connect += i-1;
break;
}
rm_linepalettecpack(vcolor[vertex]);
rm_linev3f(pcoord[vertex]);
}
rm_endclosedline();
count--;
}
}
return ST_OKAY;
}
/* ------------------------------------------------------------------------ */
/* ---------------------------- rm_draw_faces ----------------------------- */
/* ------------------------------------------------------------------------ */
static int rm_draw_faces (state_t *state, window_t *win, object_t *obj,
objinfo_t *info)
{
long count;
Vdata_t **vdata, *vcolor_v, *pcoord_v, *connect_v;
float (*pcoord)[DIMS];
int *vcolor, *connect;
char *picked;
int i, nvert, vertex, single_color;
/* Get pointers to the pertinent data sets */
vdata = obj->u.obj.vdata;
vcolor_v = get_vdata(state, vdata[VCOLOR]);
if ( (connect_v = get_vdata(state, vdata[CONNECT])) == NULL)
if ( (connect_v = get_vdata(state, vdata[MCONNECT])) == NULL)
return rm_draw_vertices(state, win, obj, info);
/* If the plist does not describe polygons, draw edges. */
if (connect_v->stats[0].rec_size < 3)
return rm_draw_edges(state, win, obj, info);
if ( (pcoord_v = get_vdata(state, vdata[PCOORD])) == NULL)
return ST_OKAY;
/* Collect connectivity information for drawing. */
connect = (int *) connect_v->data;
count = connect_v->stats[0].rec_count;
nvert = connect_v->stats[0].rec_size;
/* Set up the consolidated coordinate array pointer. */
pcoord = (float (*)[DIMS]) pcoord_v->data;
assert (pcoord_v->stats[0].type == PVFLOAT);
/* If there is no vertex color information, draw without it */
/* (use the FOREGROUND color). Otherwise, grab the color array. */
if (vcolor_v == NULL || vcolor_v->data == NULL)
{
while (count > 0)
{
rm_bgnpolygon();
for (i = nvert; i > 0; i--)
{
if ( (vertex = *(connect++)-1) == -1)
{
connect += i-1;
break;
}
rm_v3f(pcoord[vertex]);
}
rm_endpolygon();
count--;
}
}
else
{
/* Set pointers to the actual data and the size of the data */
/* sets. */
assert (vcolor_v->stats[0].type == PVINTEGER);
/* There is color information. Get it and use it to draw the */
/* appropriate shapes. */
vcolor = (int *) vcolor_v->data;
while (count > 0)
{
rm_bgnpolygon();
for (i = nvert; i > 0; i--)
{
if ((vertex = *(connect++)-1) == -1)
{
connect += i-1;
break;
}
if (i == nvert)
rm_palettecpack (vcolor[vertex]);
rm_v3f(pcoord[vertex]);
}
rm_endpolygon();
count--;
}
}
return ST_OKAY;
}
/* ------------------------------------------------------------------------ */
/* ------------------------ rm_draw_outlined_faces ------------------------ */
/* ------------------------------------------------------------------------ */
static int rm_draw_outlined_faces(state_t *state, window_t *win,
object_t *obj,
objinfo_t *info)
{
long count;
Vdata_t **vdata, *vcolor_v, *pcoord_v, *connect_v;
float (*pcoord)[DIMS];
float pcoord_outline[DIMS];
int *vcolor, *connect, *oconnect;
char *picked;
int i, j, nvert, vertex, single_color;
/* Set the width of the cylinders. */
line_width = WIN_MAXWIDTH(win) * 0.0005 * (float)(win->line_width);
/* Get pointers to the pertinent data sets */
vdata = obj->u.obj.vdata;
vcolor_v = get_vdata(state, vdata[VCOLOR]);
if ( (connect_v = get_vdata(state, vdata[CONNECT])) == NULL)
if ( (connect_v = get_vdata(state, vdata[MCONNECT])) == NULL)
return rm_draw_vertices(state, win, obj, info);
/* If the plist does not describe polygons, draw edges. */
if (connect_v->stats[0].rec_size < 3)
return rm_draw_edges(state, win, obj, info);
if ( (pcoord_v = get_vdata(state, vdata[PCOORD])) == NULL)
return ST_OKAY;
/* Collect connectivity information for drawing. */
oconnect = connect = (int *) connect_v->data;
count = connect_v->stats[0].rec_count;
nvert = connect_v->stats[0].rec_size;
/* Set up the consolidated coordinate array pointer. */
pcoord = (float (*)[DIMS]) pcoord_v->data;
assert (pcoord_v->stats[0].type == PVFLOAT);
/* If there is no vertex color information, draw without it. */
/* Otherwise, grab the color array. */
if (vcolor_v == NULL || vcolor_v->data == NULL)
{
while (count > 0)
{
/* Save connectivity pointer. */
oconnect = connect;
/* Draw the polygon. */
rm_bgnpolygon();
for (i = nvert; i > 0; i--)
{
if ( (vertex = *(connect++)-1) == -1)
{
connect += i-1;
break;
}
rm_v3f(pcoord[vertex]);
}
rm_endpolygon();
/* Start connectivity anew. */
connect = oconnect;
/* Draw the outline of the polygon, with Z values */
rm_bgnclosedline();
for (i = nvert; i > 0; i--)
{
if ( (vertex = *(connect++)-1) == -1)
{
connect += i-1;
break;
}
rm_linev3f(pcoord[vertex]);
}
rm_endclosedline();
count--;
}
}
else
{
/* Set pointers to the actual data and the size of the data */
/* sets. */
assert (vcolor_v->stats[0].type == PVINTEGER);
/* There is color information. Get it and use it to draw the */
/* appropriate shapes. */
vcolor = (int *) vcolor_v->data;
while (count > 0)
{
/* Save connectivity pointer. */
oconnect = connect;
/* Draw the polygon. */
rm_bgnpolygon();
for (i = nvert; i > 0; i--)
{
if ( (vertex = *(connect++)-1) == -1)
{
connect += i-1;
break;
}
if (i == nvert)
rm_palettecpack(vcolor[vertex]);
rm_v3f(pcoord[vertex]);
}
rm_endpolygon();
/* Start connectivity anew. */
connect = oconnect;
/* Draw the outline of the polygon, with Z values */
rm_bgnclosedline();
for (i = nvert; i > 0; i--)
{
if ( (vertex = *(connect++)-1) == -1)
{
connect += i-1;
break;
}
rm_linev3f(pcoord[vertex]);
}
rm_endclosedline();
count--;
}
}
return ST_OKAY;
}
/* Define FILENAME if you want output to a file. */
#define PICXRES pv->dv_width
#define PICYRES pv->dv_height
#define CROPMINX 0.0
#define CROPMAXX 1.0
#define CROPMINY 0.0
#define CROPMAXY 1.0
#define CAMXPOS win->cfrom[X]
#define CAMYPOS win->cfrom[Y]
#define CAMZPOS win->cfrom[Z]
#define CAMXDIR (win->at[X] - win->cfrom[X])
#define CAMYDIR (win->at[Y] - win->cfrom[Y])
#define CAMZDIR (win->at[Z] - win->cfrom[Z])
#define CAMROLL (RtFloat)((float)win->twist*0.1 + 90.0)
#define CAMFOV (RtFloat)((float)win->view_angle*0.1)
void dump_renderman (state_t *state, window_t *win, char *fname)
{
polyview_t *pv;
object_t *obj;
int i;
RtPoint CameraFrom, CameraTo;
RtFloat fov;
FILE *save_stdout, *rmfp;
#if 0
rmfp = fopen (fname, "w");
if (rmfp == NULL)
{
stprintf (state, "Could not open RenderMan output file.");
return;
}
save_stdout = stdout;
stdout = rmfp;
#endif
CameraFrom[0] = CAMXPOS;
CameraFrom[1] = CAMYPOS;
CameraFrom[2] = CAMZPOS;
CameraTo[0] = CAMXDIR;
CameraTo[1] = CAMYDIR;
CameraTo[2] = CAMZDIR;
/* Should handle both orthographic and perspective! */
fov = CAMFOV;
/* Load color array. */
for (i = 0; i < 256; i++)
{
rc[i][0] = (float)state->pal[i][0]/255.0;
rc[i][1] = (float)state->pal[i][1]/255.0;
rc[i][2] = (float)state->pal[i][2]/255.0;
}
assert (win->type == POLYVIEW);
pv = (polyview_t *)WIN_IMAGE(win);
if (WIN_FRAME(win) == NULL)
return;
obj = FRA_ROOTOBJ (WIN_FRAME(win));
/* Make sure that the object exists, has information associated */
/* with it, and has a drawing function. */
assert (obj != NULL);
assert (obj->info != NULL);
assert (obj->info->draw_fn != NULL);
/* RenderMan. */
RiBegin(fname); /* As always */
{
#ifdef FILENAME
RiDisplay(FILENAME, RI_FILE, RI_RGBA, RI_NULL);
#else
RiDisplay("RenderMan", RI_FRAMEBUFFER, RI_RGB, RI_NULL);
#endif
RiFormat((RtInt) PICXRES, (RtInt) PICYRES, 1.0);
/* Low shading rate. Doesn't seem to matter for polygon
rendering, but it does for spheres/cylinders/etc. */
RiShadingRate(16.0);
RiCropWindow(CROPMINX, CROPMAXX, CROPMINY, CROPMAXY);
/* This should probably go if we go back to the PlaceCamera
shit. */
RiOrientation (RI_RH);
RiSides (2);
RiProjection ("perspective", RI_FOV, (RtPointer)&fov, RI_NULL);
RiFrameAspectRatio ((RtFloat)((float)PICXRES/(float)PICYRES));
/*
G. Bourhis (august 93) : replace call to :
PlaceCamera(CameraFrom, CameraTo, CAMROLL);
by calls equivalent to the ones in redraw_polyview() for GL. */
RiIdentity();
RiScale(1.,1.,-1.); /* this one is not in redraw_polyview(),*/
/* I add it because Ri is right handed. */
RiRotate(WIN_TWIST(win), 0.0, 0.0, 1.0);
RiRotate(90.0-WIN_SFROM(win)[PHI]*180.0/PI, 1., 0., 0.);
RiRotate(-90.0-WIN_SFROM(win)[THETA]*180.0/PI, 0., 1., 0.);
RiRotate(-90.0, 1., 0., 0.);
RiTranslate(-CAMXPOS, -CAMYPOS, -CAMZPOS);
RiWorldBegin();
{
if (WIN_DRAW(win) == draw_faces)
rm_draw_faces (state, win, obj, obj->info);
if (WIN_DRAW(win) == draw_edges)
rm_draw_edges (state, win, obj, obj->info);
if (WIN_DRAW(win) == draw_outlined_faces || WIN_DRAW(win) == DrawTrans ||
WIN_DRAW(win) == draw_hidden_edges)
rm_draw_outlined_faces (state, win, obj, obj->info);
if (WIN_DRAW(win) == draw_vertices)
rm_draw_vertices (state, win, obj, obj->info);
}
RiWorldEnd();
}
RiEnd();
#if 0
/* Finish up the rib file. */
fflush (rmfp);
fclose (rmfp);
/* Restore stdout. */
stdout = save_stdout;
#endif
return;
}
#endif /* DIRECT_RENDERMAN */
/* ------------------------------------------------------------------------ */
/* ------------------------- DUMP_CFILE routines -------------------------- */
/* ------------------------------------------------------------------------ */
#ifdef DUMP_CFILE
/* ------------------------------------------------------------------------ */
/* ---------------------- RENDERMAN OUTPUT ROUTINES ----------------------- */
/* ------------------------------------------------------------------------ */
static FILE *rmfp = NULL;
static int rm_draw_vertices (state_t *state, window_t *win, object_t *obj,
objinfo_t *info)
{
return 0;
}
static int rm_draw_edges (state_t *state, window_t *win, object_t *obj,
objinfo_t *info)
{
return 0;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
static int num_vertices = 0;
static void rm_bgnpolygon (void)
{
num_vertices = 0;
return;
}
static void rm_v3f (float *vv)
{
/* Copy the vertex. */
fprintf (rmfp, " rp[%d][0] = %f;\n", num_vertices, vv[0]);
fprintf (rmfp, " rp[%d][1] = %f;\n", num_vertices, vv[1]);
fprintf (rmfp, " rp[%d][2] = %f;\n", num_vertices, vv[2]);
/* Increment the count. */
num_vertices++;
/* Sanity check. */
if (num_vertices > 4)
{
fprintf (stderr, "Uh oh, boss, we've got more than 4 vertices here...\n");
abort ();
}
return;
}
static void rm_endpolygon (void)
{
fprintf (rmfp, " RiPolygon( (RtInt)%d, RI_P, (RtPointer)rp, RI_NULL );\n\n",
num_vertices);
return;
}
static void rm_palettecpack (int c)
{
fprintf (rmfp, " RiColor(rc[%d]);\n", c);
}
static int rm_draw_faces (state_t *state, window_t *win, object_t *obj,
objinfo_t *info)
{
long count;
Vdata_t **vdata, *vcolor_v, *pcoord_v, *connect_v;
float (*pcoord)[DIMS];
int *vcolor, *connect;
char *picked;
int i, nvert, vertex, single_color;
/* Get pointers to the pertinent data sets */
vdata = obj->u.obj.vdata;
vcolor_v = get_vdata(state, vdata[VCOLOR]);
if ( (connect_v = get_vdata(state, vdata[CONNECT])) == NULL)
if ( (connect_v = get_vdata(state, vdata[MCONNECT])) == NULL)
return rm_draw_vertices(state, win, obj, info);
/* If the plist does not describe polygons, draw edges. */
if (connect_v->stats[0].rec_size < 3)
return rm_draw_edges(state, win, obj, info);
if ( (pcoord_v = get_vdata(state, vdata[PCOORD])) == NULL)
return ST_OKAY;
/* Collect connectivity information for drawing. */
connect = (int *) connect_v->data;
count = connect_v->stats[0].rec_count;
nvert = connect_v->stats[0].rec_size;
/* Set up the consolidated coordinate array pointer. */
pcoord = (float (*)[DIMS]) pcoord_v->data;
assert (pcoord_v->stats[0].type == PVFLOAT);
/* If there is no vertex color information, draw without it */
/* (use the FOREGROUND color). Otherwise, grab the color array. */
if (vcolor_v == NULL || vcolor_v->data == NULL)
{
while (count > 0)
{
rm_bgnpolygon();
for (i = nvert; i > 0; i--)
{
if ( (vertex = *(connect++)-1) == -1)
{
connect += i-1;
break;
}
rm_v3f(pcoord[vertex]);
}
rm_endpolygon();
count--;
}
}
else
{
/* Set pointers to the actual data and the size of the data */
/* sets. */
assert (vcolor_v->stats[0].type == PVINTEGER);
/* There is color information. Get it and use it to draw the */
/* appropriate shapes. */
vcolor = (int *) vcolor_v->data;
while (count > 0)
{
rm_bgnpolygon();
for (i = nvert; i > 0; i--)
{
if ((vertex = *(connect++)-1) == -1)
{
connect += i-1;
break;
}
if (i == nvert)
rm_palettecpack (vcolor[vertex]);
rm_v3f(pcoord[vertex]);
}
rm_endpolygon();
count--;
}
}
return ST_OKAY;
}
void dump_renderman (state_t *state, window_t *win, char *fname)
{
polyview_t *pv;
object_t *obj;
int i;
assert (win->type == POLYVIEW);
pv = (polyview_t *)WIN_IMAGE(win);
rmfp = fopen (fname, "w");
if (rmfp == NULL)
{
stprintf (state, "Could not open output file.");
return;
}
fprintf (rmfp, "/* NCSA Polyview 3.0 Renderman output file. */\n\n");
fprintf (rmfp, "/* National Center for Supercomputing Applications */\n");
fprintf (rmfp, "/* University of Illinois at Urbana-Champaign */\n");
fprintf (rmfp, "/* polyview@ncsa.uiuc.edu */\n\n");
fprintf (rmfp, "#include <ri.h>\n\n");
fprintf (rmfp, "/* Define FILENAME if you want output to a file. */\n\n");
fprintf (rmfp, "#define PICXRES %d\n", pv->dv_width);
fprintf (rmfp, "#define PICYRES %d\n\n", pv->dv_height);
fprintf (rmfp, "#define CROPMINX 0.0\n");
fprintf (rmfp, "#define CROPMAXX 1.0\n");
fprintf (rmfp, "#define CROPMINY 0.0\n");
fprintf (rmfp, "#define CROPMAXY 1.0\n\n");
fprintf (rmfp, "#define CAMXPOS %f\n", win->cfrom[X]);
fprintf (rmfp, "#define CAMYPOS %f\n", win->cfrom[Y]);
fprintf (rmfp, "#define CAMZPOS %f\n\n", win->cfrom[Z]);
fprintf (rmfp, "#define CAMXDIR %f\n", win->at[X] - win->cfrom[X]);
fprintf (rmfp, "#define CAMYDIR %f\n", win->at[Y] - win->cfrom[Y]);
fprintf (rmfp, "#define CAMZDIR %f\n\n", win->at[Z] - win->cfrom[Z]);
/* ??? */
fprintf (rmfp, "#define CAMROLL 0.0\n\n");
/* ??? */
fprintf (rmfp, "#define CAMZOOM 4.5\n\n");
fprintf (rmfp, "RtPoint CameraFrom = { CAMXPOS, CAMYPOS, CAMZPOS},\n");
fprintf (rmfp, " CameraTo = { CAMXDIR, CAMYDIR, CAMZDIR};\n\n");
fprintf (rmfp, "main()\n");
fprintf (rmfp, "{\n");
fprintf (rmfp, " RiBegin(RI_NULL); /* As always */\n\n");
fprintf (rmfp, " /* Output image characteristics */\n");
fprintf (rmfp, "#ifdef FILENAME\n");
fprintf (rmfp, " /* output to given file */\n");
fprintf (rmfp, " RiDisplay(FILENAME, RI_FILE, RI_RGBA, RI_NULL); \n");
fprintf (rmfp, "#else\n");
fprintf (rmfp, " RiDisplay(\"RenderMan\", RI_FRAMEBUFFER, RI_RGB, RI_NULL);\n");
fprintf (rmfp, "#endif\n");
fprintf (rmfp, " RiFormat((RtInt) PICXRES, (RtInt) PICYRES, 1.0); /* image resolution */\n");
fprintf (rmfp, " RiShadingRate(1.0); /* Good quality, use 0.25 for better. */\n");
fprintf (rmfp, " /* region of image rendered */\n");
fprintf (rmfp, " RiCropWindow(CROPMINX, CROPMAXX, CROPMINY, CROPMAXY);\n\n");
fprintf (rmfp, " /* Nature of the projection to the image plane */\n");
fprintf (rmfp, " RiProjection(\"perspective\", RI_NULL); /* perspective view */\n\n");
fprintf (rmfp, " /* Camera characteristics */\n");
fprintf (rmfp, " FrameCamera((float)PICXRES*CAMZOOM, (float)PICXRES, (float)PICYRES);\n\n");
fprintf (rmfp, " /* Camera position and orientation */\n");
fprintf (rmfp, " CameraTo[0] -= CameraFrom[0];\n");
fprintf (rmfp, " CameraTo[1] -= CameraFrom[1];\n");
fprintf (rmfp, " CameraTo[2] -= CameraFrom[2];\n");
fprintf (rmfp, " PlaceCamera(CameraFrom, CameraTo, CAMROLL);\n\n");
fprintf (rmfp, " /* Now describe the world */\n");
fprintf (rmfp, " RiWorldBegin();\n");
fprintf (rmfp, " Go();\n");
fprintf (rmfp, " RiWorldEnd();\n\n");
fprintf (rmfp, " RiEnd();\n\n");
fprintf (rmfp, " return 0;\n");
fprintf (rmfp, "}\n\n\n");
fprintf (rmfp, "RtColor rc[256] = {\n");
for (i = 0; i < 256; i++)
{
fprintf (rmfp, " { %f, %f, %f },\n", (float)state->pal[i][0]/255.0,
(float)state->pal[i][1]/255.0, (float)state->pal[i][2]/255.0);
}
fprintf (rmfp, "};\n\n");
fprintf (rmfp, "Go() {\n");
fprintf (rmfp, " RtPoint rp[4];\n\n");
if (WIN_FRAME(win) == NULL)
return;
obj = FRA_ROOTOBJ (WIN_FRAME(win));
/* Make sure that the object exists, has information associated */
/* with it, and has a drawing function. */
assert (obj != NULL);
assert (obj->info != NULL);
assert (obj->info->draw_fn != NULL);
/* Load default color, in case none are being used. */
fprintf (rmfp, " rc[0] = %f;\n", 0.8);
fprintf (rmfp, " rc[1] = %f;\n", 0.8);
fprintf (rmfp, " rc[2] = %f;\n", 0.8);
fprintf (rmfp, " RiColor(rc);\n\n");
rm_draw_faces (state, win, obj, obj->info);
fprintf (rmfp, "}\n\n");
fflush (rmfp);
fclose (rmfp);
rmfp = NULL;
return;
}
#endif /* DUMP_CFILE */
#endif /* RENDERMAN */
/* DO NOT PUT CODE HERE! */